package com.sduept.nwld.dataserver.rest;


import com.alibaba.fastjson.JSONObject;
import com.sduept.bigdata.fault.entity.FaultRecord;
import com.sduept.bigdata.fault.manager.FaultManager;
import com.sduept.bigdata.fault.manager.FaultRecordQueryManager;
import com.sduept.cim.ledger.excetpion.ManagementUnitException;
import com.sduept.cim.ledger.model.ManagementUnitDict;
import com.sduept.cim.ledger.services.ManagementUnitService;
import com.sduept.core.dao.SuperDAO;
import com.sduept.nwld.dataserver.manager.countanalyse.ProtectAnalysisManger;
import com.sduept.nwld.dataserver.manager.statistics.StatisticsCommonManager;
import com.sduept.nwld.dataserver.manager.statistics.TransmissionLineManager;
import com.sduept.nwld.dataserver.model.countanalyse.TansmissionLineInfo;
import com.sduept.utils.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.Map.Entry;

/**
 *厂站输电设备故障统计
 */
@RestController
@RequestMapping("/transmissionline")
public class TransmissionLineService {
	//TODO:ManagementUnitService 替换需要测试
	@Autowired
	private SuperDAO dao;
	@Autowired
	private ProtectAnalysisManger pa;

	@Autowired
	private FaultManager fman;
	@Autowired
	private FaultRecordQueryManager frqm;
	@Autowired
	private StatisticsCommonManager comM;
	@Autowired
	private TransmissionLineManager lineM;
	@Autowired
	private ManagementUnitService unitM;

	@GetMapping("/getLineFaultCountData/{startYear}/{endYear}/{voltage}")
	public String getLineFaultCountDataByCondition(@PathVariable("startYear") String startYear, @PathVariable("endYear") String endYear, @PathVariable("voltage") String voltage) {
		StringBuffer buffer = new StringBuffer();
		buffer.append("[");
		List<FaultRecord> faultRecords = comM.getFaultRecordsByCondition(startYear, endYear, voltage, "线路");
		Map<Integer, List<FaultRecord>> map = comM.genFaultRecordMapByYear(faultRecords);
		comM.completeMapByYear(startYear, endYear, map);
		Integer vol = null;
		if(!"0".equals(voltage)) {
			vol = Integer.parseInt(voltage);
		}
		for (Integer year : map.keySet()) {
			List<FaultRecord> faults = map.get(year);
			List<TansmissionLineInfo> list = lineM.getTansmissionLineInfos(year, vol);
			TansmissionLineInfo info = new TansmissionLineInfo();
			if(list.size()>0) {
				info = list.get(0);
			} else {
				info.setLength(0d);
				info.setIncreaseLength(0D);
			}
			double d = 0;
			if(faults.size() > 0 && info.getLength() != null && info.getLength() > 0){
				d =((double)faults.size())/(info.getLength()/100);
			}
			buffer.append("{year:"+year+",value:{lineLength:"+info.getLength()+",newAddLength:"+info.getNewAdd()+",faultNum:"+faults.size()+",faultRate:"+d+"}},");
		}
		buffer.append("]");
		return JSONObject.parse(buffer.toString()).toString();
	}

	/**
	 * 获取历年输电线的长度，条数，新增长度故障次数
	 *
	 * @return
	 */
	@GetMapping("/getLineRunData")
	public String getLineRunData() {
		StringBuffer buffer = new StringBuffer();
		buffer.append("[");


		List<TansmissionLineInfo>  lt = dao.findAll(TansmissionLineInfo.class);
		for (TansmissionLineInfo t : lt) {
			//			 	String sql = " etype='线路' and faultTime >= '"+t.getYear()+"-01-01 00:00:00' and faultTime <'"+t.getYear()+"-12-31 11:59:59'";
			//				List<FaultRecord>  ltf = dao.findByCondition(sql, FaultRecord.class);
			String sy = t.getYear()+"-01-01 00:00:00";
			String ey = t.getYear()+"-12-31 23:59:59";
			Date sd = DateUtil.getDateByString(sy, DateUtil.pattern_ymdhms);
			Date ed = DateUtil.getDateByString(ey, DateUtil.pattern_ymdhms);
			List<FaultRecord> ltf = dao.findByCondition(FaultRecord.class, " etype='线路'  and faultTime >= ? and faultTime < ?", sd,ed);
			double d = 0;
			if(ltf.size() > 0 && t.getLength() != null && t.getLength() > 0){
				d =((double)ltf.size())/(t.getLength()/100);
			}
			buffer.append("{year:"+t.getYear()+",value:{lineLength:"+t.getLength()+",lineNum:0"+",newAddLength:"+t.getNewAdd()+",faultNum:"+ltf.size()+",faultRate:"+d+"}},");
		}
		buffer.append("]");
		return JSONObject.parse(buffer.toString()).toString();
	}

	/**
	 * 根据年、电压等级统计输电线路故障
	 * @param year
	 * @param voltage
	 * @return
	 */
	@GetMapping("/getLineFaultByYearAndVoltage/{year}/{voltage}")
	public String getLineFaultByYearAndVoltage(@PathVariable("year") String year, @PathVariable("voltage") String voltage) {
		// 根据年、电压等级获取类型为线路的故障
		List<FaultRecord> faultRecords = comM.getFaultRecordsByCondition(year, year, voltage, "线路");
		return comM.genJSONData(faultRecords);
	}


	/**
	 * 获取每年各单位输电线故障类型次数
	 * @param year
	 * @return
	 */
	@GetMapping("/getLineFaultTypeDataByYear/{year}")
	@Deprecated
	public String getLineFaultTypeDataByYear(@PathVariable("year") int year) {
		if(year==0){
			return "{}";
		}
		StringBuffer buff = new StringBuffer();
		List<?> list = pa.getLineFaultTypeDataByYear(year);
		//按故障类型统计
		Map<String,Integer> faultTypeCounts = new HashMap<>();
		//各单位各故障类型统计{rank:[]}
		Map<String,int[]> companyTypeCounts = new HashMap<>();
		//本年所有的故障类型
		List<String> allFaultTypes=new ArrayList<String>();
		//本年所有的调管单位
		List<String> allRanks=new ArrayList<String>();
		for(Object object:list){
			Object[] objs = (Object[]) object;
			String faultType=String.valueOf(objs[0]);
			String rank=String.valueOf(objs[1]);
			int count=Integer.parseInt(String.valueOf(objs[2]));
			if(!allRanks.contains(rank)){
				allRanks.add(rank);
			}
			Integer c=faultTypeCounts.get(faultType);
			if(c==null){
				c=1;
			}else{
				c+=count;
			}
			faultTypeCounts.put(faultType, c);
		}
		Map<String,Integer> newfaultTypeCounts=sortByValue(faultTypeCounts);
		allFaultTypes.addAll(newfaultTypeCounts.keySet());
		for(String ft:allFaultTypes){
			companyTypeCounts.put(ft, new int[allRanks.size()]);
		}
		for(Object object:list){
			Object[] objs = (Object[]) object;
			String faultType=String.valueOf(objs[0]);
			String rank=String.valueOf(objs[1]);
			int count=Integer.parseInt(String.valueOf(objs[2]));
			companyTypeCounts.get(faultType)[allRanks.indexOf(rank)]+=count;
		}
		String ranksStr = JSONObject.toJSONString(allRanks);
		buff.append("{\"allRanks\":"+ranksStr+",");
		String faultTypeStr = JSONObject.toJSONString(newfaultTypeCounts);
		buff.append("\"faultTypeCounts\":"+faultTypeStr+",");
		String companyTypeStr = JSONObject.toJSONString(companyTypeCounts);
		buff.append("\"companyTypeCounts\":"+companyTypeStr+"}");
		return buff.toString();
	}

	/**
	 * 获取每一年输电线路故障综合原因
	 *
	 * @param year
	 * @return
	 */
	@GetMapping("/getLineFaultByYear/{year}/{voltage}")
	public String getLineFaultByYear(@PathVariable("year") int year,@PathVariable("voltage") String voltage) {
		if(year==0){
			return "{}";
		}

		Integer vol = null;
		if(!"0".equals(voltage)) {
			vol = Integer.parseInt(voltage);
		}

		StringBuffer buff = new StringBuffer();
		String sy = year+"-01-01 00:00:00";
		String ey = year+"-12-31 23:59:59";
		Date start = DateUtil.getDateByString(sy, DateUtil.pattern_ymdhms);
		Date end = DateUtil.getDateByString(ey, DateUtil.pattern_ymdhms);
		//List<FaultRecord> alls=fman.find500KvFault(sy, ey);
		List<FaultRecord> alls=frqm.findFaultByTimeEtypeVoltage(start, end,vol,"线路");
		//月份统计
		int[] monthCounts=new int[12];
		//故障原因统计
		Map<String,int[]> faultReasonCounts = new HashMap<>();
		//故障原因总计
		List<Object[]> faultReasonTotalCounts = new ArrayList<>();
		for(FaultRecord f:alls){
			DateTime dt = new DateTime(f.getFaultTime());
			int month = dt.getMonthOfYear();
			monthCounts[month-1]++;
			//调管单位月度统计
			String reason  = f.getFaultReson();
			if(null != reason) {
				int[] reasonData = faultReasonCounts.get(reason);
				if(reasonData == null) {
					reasonData = new int[12];
					faultReasonCounts.put(reason, reasonData);
				}
				reasonData[month-1]++;
			}
		}
		for(Map.Entry<String,int[]> et : faultReasonCounts.entrySet()){
			String key = et.getKey();
			int[] v = et.getValue();
			int c = 0;
			for(int i : v) {
				c += i;
			}
			Object[] os = new Object[] {key,c};
			faultReasonTotalCounts.add(os);
		}
		Collections.sort(faultReasonTotalCounts, new Comparator<Object[]>() {
			@Override
			public int compare(Object[] o1,Object[] o2) {
				return (int)o2[1]-(int)o1[1];
			}
		});
		String monthjsonstr = JSONObject.toJSONString(monthCounts);
		buff.append("{\"months\":"+monthjsonstr+",");
		String faultReasonCountstr = JSONObject.toJSONString(faultReasonCounts);
		buff.append("\"faultReasonCounts\":"+faultReasonCountstr+",");
		String faultReasonTotalCountstr = JSONObject.toJSONString(faultReasonTotalCounts);
		buff.append("\"faultReasonTotalCounts\":"+faultReasonTotalCountstr);
		buff.append("}");
		return buff.toString();
	}

	/**
	 * 获取每一年输电线路故障具体原因
	 *
	 * @param year
	 * @return  {months:[0,0,0,0,0],faultType:{"单瞬":10,"":0},companyMonthCounts:{rankName:[0,0]},}
	 */
	@GetMapping("/getLineFaultByYearAndType/{year}/{faultReason}/{voltage}")
	public String getLineFaultDetailByYearAndType( @PathVariable("year") int year,
												   @PathVariable("faultReason") String faultReason,@PathVariable("voltage") int voltage){
		StringBuffer buff = new StringBuffer();
		if(year==0){
			return "{}";
		}
		Integer fv = voltage == 0 ?null : voltage;
		String sy = year+"-01-01 00:00:00";
		String ey = year+"-12-31 23:59:59";
		//月份统计
		int[] monthCounts=new int[12];
		//按类型统计
		Map<String,Integer> faultTypeCount = new HashMap<>();
		//调管单位月度统计
		//		Map<String,int[]> companyMonthCounts = new HashMap<>();

		Map<String, int[]> companyMonthCounts = genDeptMap(12);
		//		Map<String, String> deptMap = unitM.getMaintanceDeptsRelationMap();

		//每个调管单位总计
		List<Object[]> companyTotalCounts = new ArrayList<>();
		List<FaultRecord> alls = fman.findFault(fv, sy, ey, "线路", null, null,null, new String[] {faultReason});
		for(FaultRecord f:alls){
			DateTime dt = new DateTime(f.getFaultTime());
			int month = dt.getMonthOfYear();
			monthCounts[month-1]++;
			//类型
			String ftype = f.getFaultType();
			if(StringUtils.isNotEmpty(ftype)) {
				Integer c = faultTypeCount.get(ftype);
				if(c == null) {
					c = 1;
				}else{
					c++;
				}
				faultTypeCount.put(ftype, c);
			}
			//调管单位月度统计
			String rank  = f.getRank();
			ManagementUnitDict pDept;
			try {
				pDept = unitM.getManagementUnitByName(rank);
				if(null != pDept) {
					int[] rankData = companyMonthCounts.get(pDept.getName());
					if(rankData == null) {
						rankData = new int[12];
						companyMonthCounts.put(pDept.getName(), rankData);
					}
					rankData[month-1]++;
				}
			} catch (ManagementUnitException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		for(Map.Entry<String,int[]> et : companyMonthCounts.entrySet()){
			String key = et.getKey();
			int[] v = et.getValue();
			int c = 0;
			for(int i : v) {
				c += i;
			}
			Object[] os = new Object[] {key,c};
			companyTotalCounts.add(os);
		}
		String monthjsonstr = JSONObject.toJSONString(monthCounts);
		buff.append("{\"months\":"+monthjsonstr+",");
		String faultTypeCountstr = JSONObject.toJSONString(sortByValue(faultTypeCount));
		buff.append("\"faultTypeCount\":"+faultTypeCountstr+",");
		String companyMonthstr = JSONObject.toJSONString(companyMonthCounts);
		buff.append("\"companyMonthCount\":"+companyMonthstr+",");
		Collections.sort(companyTotalCounts, new Comparator<Object[]>() {
			@Override
			public int compare(Object[] o1,Object[] o2) {
				return (int)o2[1]-(int)o1[1];
			}
		});
		String companyTotalCountstr = JSONObject.toJSONString(companyTotalCounts);
		buff.append("\"companyTotalCount\":"+companyTotalCountstr+",");
		buff.append("\"total\":"+alls.size());
		buff.append("}");
		return buff.toString();
	}

	private Map<String, int[]> genDeptMap(int size) {
		Map<String, int[]> deptCountMap = new HashMap<String, int[]>();//名-数量
		List<ManagementUnitDict> allDepts;
		try {
			allDepts = unitM.getAllMaintenanceScopes();
			for (ManagementUnitDict dept : allDepts) {
				deptCountMap.put(dept.getName(), new int[size]);
			}
		} catch (ManagementUnitException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return deptCountMap;
	}

	@GetMapping("/getLineFaultByYearIntervalAndType/{startYear}/{endYear}/{faultType}/{voltage}")
	public String getLineFaultDetailByYearAndType( @PathVariable("startYear") int syear,@PathVariable("endYear") int eyear
			,@PathVariable("faultType") String faultType
			,@PathVariable("voltage") int voltage){
		StringBuffer buff = new StringBuffer();
		if(syear == 0 || eyear == 0){
			return "{}";
		}
		String sy = syear+"-01-01 00:00:00";
		String ey = eyear+"-12-31 23:59:59";
		//月份统计
		Map<String,int[]> monthCounts = new TreeMap<>(new Comparator<String>() {
			@Override
			public int compare(String o1,String o2) {
				return Integer.parseInt(o1)-Integer.parseInt(o2);
			}
		});

		for(int i = syear;i < eyear+1 ; i++) {
			monthCounts.put(String.valueOf(i), new int[12]);
		}
		//年度总计
		Map<String,Integer> yearCounts = new HashMap<>();
		//年统计
		Map<String,int[]> companyYearCounts = new HashMap<>();

		//按类型统计(根据value排序)
		Map<String,Integer> faultTypeCount = new HashMap<>();

		Integer fv = voltage == 0 ?null : voltage;

		List<FaultRecord> alls = fman.findFault(fv, sy, ey, "线路", null, null,null, new String[] {faultType});

		for(FaultRecord f : alls) {
			DateTime dt = new DateTime(f.getFaultTime());
			int year = dt.getYear();
			int month = dt.getMonthOfYear();
			monthCounts.get(String.valueOf(year))[month-1]++;
			//构造每年总数
			Integer n  = yearCounts.get(String.valueOf(year));
			if(n == null) {
				n = 1;
			}else{
				n++;
			}
			yearCounts.put(String.valueOf(year), n);
			//构造按所属单位每年的曲线数据
			String rank  = f.getRank();
			if(null != rank) {
				int[] rankline = companyYearCounts.get(rank);
				if(rankline == null) {
					rankline = new int[eyear-syear+1];
					companyYearCounts.put(rank, rankline);
				}
				rankline[year-syear]++;
			}
			//类型
			String ftype = f.getFaultType();
			if(StringUtils.isNotEmpty(ftype)) {
				Integer c = faultTypeCount.get(ftype);
				if(c == null) {
					c = 1;
				}else{
					c++;
				}
				faultTypeCount.put(ftype, c);
			}

		}
		//所属地区统计
		List<Object[]> ranks = new ArrayList<>();
		for(Map.Entry<String,int[]> et : companyYearCounts.entrySet()) {
			String key = et.getKey();
			int[] v = et.getValue();
			int c = 0;
			for(int i : v) {
				c += i;
			}
			Object[] os = new Object[] {key,c};
			ranks.add(os);
		}

		String monthjsonstr = JSONObject.toJSONString(monthCounts);

		buff.append("{\"months\":"+monthjsonstr+",");

		String companyCountsstr = JSONObject.toJSONString(companyYearCounts);

		buff.append("\"companyYearCounts\":"+companyCountsstr+",");
		Collections.sort(ranks, new Comparator<Object[]>() {
			@Override
			public int compare(Object[] o1,Object[] o2) {
				return (int)o2[1]-(int)o1[1];
			}
		});
		String ranksjsonstr = JSONObject.toJSONString(ranks);
		buff.append("\"ranks\":"+ranksjsonstr+",");
		String yearCountstr = JSONObject.toJSONString(yearCounts);
		buff.append("\"yearCounts\":"+yearCountstr+",");
		String faultTypeCountstr = JSONObject.toJSONString(sortByValue(faultTypeCount));
		buff.append("\"faultTypeCount\":"+faultTypeCountstr+",");
		buff.append("\"total\":"+alls.size()+"");
		buff.append("}");
		return buff.toString();
	}

	@GetMapping("/getLineFaultDetail/{startYear}/{endYear}/{faultReason}/{voltage}/{faultType}")
	public String getLineFaultDetails( @PathVariable("startYear") int syear,@PathVariable("endYear") int eyear
			,@PathVariable("faultReason") String faultReason
			,@PathVariable("faultType") String faultType
			,@PathVariable("voltage") int voltage){
		if(syear == 0 || eyear == 0){
			return "{}";
		}
		String sy = syear+"-01-01 00:00:00";
		String ey = eyear+"-12-31 23:59:59";
		Integer fv = voltage == 0 ?null : voltage;
		List<FaultRecord> alls = fman.findFault(fv, sy, ey, "线路", null, null,faultType, new String[] {faultReason});
		return JSONObject.toJSONString(alls);
	}
	private Map<String,Integer> sortByValue(Map<String,Integer> map){
		List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(map.entrySet());
		Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
			@Override
			public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
				return o2.getValue()-o1.getValue();
			}
		});
		Map<String,Integer> result = new LinkedHashMap<String,Integer>();
		for (Map.Entry<String,Integer> entry : list) {
			result.put(entry.getKey(), entry.getValue());
		}
		return result;
	}
}
